package world

import (
	"strings"
	"sync"
)

var (
	ApplyMgr = newApplyMgr()
)

type applyMgr struct {
	funcList []*FuncItem
	mutex    sync.Mutex
}

func newApplyMgr() *applyMgr {
	return &applyMgr{
		funcList: make([]*FuncItem, 0, 64),
	}
}

func (this *applyMgr) RegisterFunc(moduleName string, funcDefinition func() []error) {
	this.mutex.Lock()
	defer this.mutex.Unlock()

	funcItemObj := newFuncItem(moduleName, funcDefinition)
	this.funcList = append(this.funcList, funcItemObj)
}

func (this *applyMgr) CallByModuleName(moduleName string) (errList []error) {
	this.mutex.Lock()
	defer this.mutex.Unlock()

	for _, item := range this.funcList {
		if item.moduleName != moduleName {
			continue
		}

		errorList := item.funcDefinition()
		if errorList != nil && len(errorList) > 0 {
			errList = append(errList, errorList...)
		}
	}

	return
}

func (this *applyMgr) CallByModuleNamePrefix(moduleNamePrefix string) (errList []error) {
	this.mutex.Lock()
	defer this.mutex.Unlock()

	for _, item := range this.funcList {
		if strings.HasPrefix(item.moduleName, moduleNamePrefix) == false {
			continue
		}

		errorList := item.funcDefinition()
		if errorList != nil && len(errorList) > 0 {
			errList = append(errList, errorList...)
		}
	}

	return
}

func (this *applyMgr) CallAll() (errList []error) {
	this.mutex.Lock()
	defer this.mutex.Unlock()

	for _, item := range this.funcList {
		errorList := item.funcDefinition()
		if errorList != nil && len(errorList) > 0 {
			errList = append(errList, errorList...)
		}
	}

	return
}
